#include <stdio.h>
#include "cmodel.h"
#include "mobilenetv2_param.h"
#include "img_in.h"
#include "img_out_ref.h"

featureMap img_a;
featureMap img_b;
featureMap img_tmp;
DTYPE buff_a[20000];
DTYPE buff_b[20000];
DTYPE buff_tmp[20000];

void load_img(char *filename){
}

void forward(featureMap img_in){
    img_a.data = buff_a;
    img_b.data = buff_b;
    img_tmp.data = buff_tmp;
RELU_ON
    conv2d_s1p1k3_b(&img_in, &pre_0_weight, &pre_0_bias, &img_b);                                   // pre.0
/********************************************************************************************************************/
    conv2d_pw_b(&img_b, &stage1_residual_0_weight, &stage1_residual_0_bias, &img_a);                // stage1.residual.0
    conv2d_s1p1k3_dw_b(&img_a, &stage1_residual_3_weight, &stage1_residual_3_bias, &img_tmp);       // stage1.residual.3
RELU_OFF
    conv2d_pw_b(&img_tmp, &stage1_residual_6_weight, &stage1_residual_6_bias, &img_a);              // stage1.residual.6
/********************************************************************************************************************/
RELU_ON
    conv2d_pw_b(&img_a, &stage2_0_residual_0_weight, &stage2_0_residual_0_bias, &img_b);            // stage2.0.residual.0
    conv2d_s2p1k3_dw_b(&img_b, &stage2_0_residual_3_weight, &stage2_0_residual_3_bias, &img_a);     // stage2.0.residual.3 [16, 16, 16]
RELU_OFF
    conv2d_pw_b(&img_a, &stage2_0_residual_6_weight, &stage2_0_residual_6_bias, &img_b);            // stage2.0.residual.6
RELU_ON
    conv2d_pw_b(&img_b, &stage2_1_residual_0_weight, &stage2_1_residual_0_bias, &img_a);            // stage2.1.residual.0
    conv2d_s1p1k3_dw_b(&img_a, &stage2_1_residual_3_weight, &stage2_1_residual_3_bias, &img_tmp);     // stage2.1.residual.3
RELU_OFF
    conv2d_pw_b(&img_tmp, &stage2_1_residual_6_weight, &stage2_1_residual_6_bias, &img_a);            // stage2.1.residual.6 [16, 16, 16]
    mat_add(&img_a, &img_b);
/********************************************************************************************************************/
RELU_ON
    conv2d_pw_b(&img_a, &stage3_0_residual_0_weight, &stage3_0_residual_0_bias, &img_b);            // stage3.0.residual.0
    conv2d_s2p1k3_dw_b(&img_b, &stage3_0_residual_3_weight, &stage3_0_residual_3_bias, &img_a);     // stage3.0.residual.3
RELU_OFF
    conv2d_pw_b(&img_a, &stage3_0_residual_6_weight, &stage3_0_residual_6_bias, &img_b);            // stage3.0.residual.6
RELU_ON
    conv2d_pw_b(&img_b, &stage3_1_residual_0_weight, &stage3_1_residual_0_bias, &img_a);            // stage3.1.residual.0
    conv2d_s1p1k3_dw_b(&img_a, &stage3_1_residual_3_weight, &stage3_1_residual_3_bias, &img_tmp);     // stage3.1.residual.3
RELU_OFF
    conv2d_pw_b(&img_tmp, &stage3_1_residual_6_weight, &stage3_1_residual_6_bias, &img_a);            // stage3.1.residual.6
    mat_add(&img_a, &img_b);
/********************************************************************************************************************/
RELU_ON
    conv2d_pw_b(&img_a, &stage4_residual_0_weight, &stage4_residual_0_bias, &img_b);            // stage4.0.residual.0
    conv2d_s2p1k3_dw_b(&img_b, &stage4_residual_3_weight, &stage4_residual_3_bias, &img_a);     // stage4.0.residual.3
RELU_OFF
    conv2d_pw_b(&img_a, &stage4_residual_6_weight, &stage4_residual_6_bias, &img_b);            // stage4.0.residual.6
/********************************************************************************************************************/
RELU_ON
    conv2d_pw_b(&img_b, &conv1_0_weight, &conv1_0_bias, &img_a);                                    // conv1.0
    avg_pool2d_4x4_inplace(&img_a);
RELU_OFF
    conv2d_pw_b(&img_a, &conv2_weight, &conv2_bias, &img_b);                                        // conv2
    printf("img_b info %d, %d, %d\n", img_b.channels, img_b.height, img_b.width);
}

int main(int argc, char const *argv[])
{
    int err;
    int len;
    
    printf("%d, %d, %d\n", img_in.channels, img_in.width, img_in.height);
    forward(img_in);
    err = 0;
    len = img_b.channels * img_b.width * img_b.height;
    for (int i = 0; i < 10; i++)
    {
        err += ABS(img_b.data[i] - img_out_ref.data[i]);
        printf("%d\n", ABS(img_b.data[i] - img_out_ref.data[i]));
    }
    debug("err:%d\n", err);
    save_feature_map_to_file(img_b, "img_out_c.txt");
    return 0;
}


